[IA64] Use ppn to store io type.
authorAlex Williamson <alex.williamson@hp.com>
Tue, 1 Apr 2008 15:42:52 +0000 (09:42 -0600)
committerAlex Williamson <alex.williamson@hp.com>
Tue, 1 Apr 2008 15:42:52 +0000 (09:42 -0600)
Instead of using 3 extra bits in pte to store the io type, only one bit
is used to mark the page as an IO page and the type is stored in the ppn
field.  This both save 2 bits and allow many more io types.

Move the VTi memory map to arch-ia64/hvm/memmap.h

Signed-off-by: Tristan Gingold <tgingold@free.fr>
12 files changed:
xen/arch/ia64/vmx/mmio.c
xen/arch/ia64/vmx/sioemu.c
xen/arch/ia64/vmx/vlsapic.c
xen/arch/ia64/vmx/vmmu.c
xen/arch/ia64/vmx/vmx_fault.c
xen/arch/ia64/vmx/vmx_init.c
xen/arch/ia64/vmx/vtlb.c
xen/arch/ia64/xen/mm.c
xen/include/asm-ia64/linux-xen/asm/pgtable.h
xen/include/asm-ia64/vmmu.h
xen/include/public/arch-ia64.h
xen/include/public/arch-ia64/hvm/memmap.h [new file with mode: 0644]

index 44c546131052456995fc2db0c1c9c48d00a48edf..067c4836b4bde55730706ccb9711706272c6b3e7 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/hvm/vacpi.h>
 #include <asm/hvm/support.h>
 #include <public/hvm/save.h>
+#include <public/arch-ia64/hvm/memmap.h>
 #include <public/arch-ia64/sioemu.h>
 #include <asm/sioemu.h>
 
@@ -352,11 +353,9 @@ static void legacy_io_access(VCPU *vcpu, u64 pa, u64 *val, size_t s, int dir)
     return;
 }
 
-static void mmio_access(VCPU *vcpu, u64 src_pa, u64 *dest, size_t s, int ma, int dir, u64 pte)
+static void mmio_access(VCPU *vcpu, u64 src_pa, u64 *dest, size_t s, int ma, int dir, u64 iot)
 {
-    unsigned long iot = pte & GPFN_IO_MASK;
-
-    perfc_incra(vmx_mmio_access, iot >> 56);
+    perfc_incra(vmx_mmio_access, iot & 0x7);
     switch (iot) {
     case GPFN_PIB:       
         if (ma != 4)
@@ -367,8 +366,6 @@ static void mmio_access(VCPU *vcpu, u64 src_pa, u64 *dest, size_t s, int ma, int
         else
             *dest = vlsapic_read(vcpu, src_pa, s);
         break;
-    case GPFN_GFW:
-        break;
     case GPFN_IOSAPIC:
         if (!dir)
             viosapic_write(vcpu, src_pa, s, *dest);
@@ -394,7 +391,7 @@ enum inst_type_en { SL_INTEGER, SL_FLOATING, SL_FLOATING_FP8 };
 /*
    dir 1: read 0:write
  */
-void emulate_io_inst(VCPU *vcpu, u64 padr, u64 ma, u64 pte)
+void emulate_io_inst(VCPU *vcpu, u64 padr, u64 ma, u64 iot)
 {
     REGS *regs;
     IA64_BUNDLE bundle;
@@ -536,8 +533,6 @@ void emulate_io_inst(VCPU *vcpu, u64 padr, u64 ma, u64 pte)
     }
 
     if (vcpu->domain->arch.is_sioemu) {
-        unsigned long iot = pte & GPFN_IO_MASK;
-
         if (iot != GPFN_PIB && iot != GPFN_IOSAPIC) {
             sioemu_io_emulate(padr, data, data1, update_word);
             return;
@@ -545,10 +540,10 @@ void emulate_io_inst(VCPU *vcpu, u64 padr, u64 ma, u64 pte)
     }
 
     if (size == 4) {
-        mmio_access(vcpu, padr + 8, &data1, 1 << 3, ma, dir, pte);
+        mmio_access(vcpu, padr + 8, &data1, 1 << 3, ma, dir, iot);
         size = 3;
     }
-    mmio_access(vcpu, padr, &data, 1 << size, ma, dir, pte);
+    mmio_access(vcpu, padr, &data, 1 << size, ma, dir, iot);
 
     emulate_io_update(vcpu, update_word, data, data1);
 }
index dad0d414fa4c25d2d55d6da1f0f2d16bd57461a7..526d8c087f4c61206713faaf9619c1a4cffcb562 100644 (file)
@@ -166,8 +166,11 @@ sioemu_add_io_physmap (struct domain *d, unsigned long start,
     unsigned long i;
     int res;
 
+    /* Convert to ppn.  */
+    type <<= PAGE_SHIFT;
+
     /* Check type.  */
-    if (type == 0 || (type & GPFN_IO_MASK) != type)
+    if (type == 0 || (type & _PAGE_PPN_MASK) != type)
         return -EINVAL;
     if ((start & (PAGE_SIZE -1)) || (size & (PAGE_SIZE - 1)))
         return -EINVAL;
@@ -180,7 +183,7 @@ sioemu_add_io_physmap (struct domain *d, unsigned long start,
 
     /* Set.  */
     for (i = start; i < start + size; i += PAGE_SIZE) {
-        res = __assign_domain_page(d, i, type, ASSIGN_writable);
+        res = __assign_domain_page(d, i, type, ASSIGN_writable | ASSIGN_io);
         if (res != 0)
             return res;
     }
index d6a180684009e303e160995767bbdbdd0a262404..124b4e892ba27b2ad73552e6e2ead70eff9bf850 100644 (file)
@@ -47,6 +47,7 @@
 #include <xen/domain.h>
 #include <asm/hvm/support.h>
 #include <public/hvm/save.h>
+#include <public/arch-ia64/hvm/memmap.h>
 
 #ifdef IPI_DEBUG
 #define IPI_DPRINTK(x...) printk(x)
index 851fd5bdede7c6ff9fb18a1fb637708b513441c2..4fb9593c055704ad0c01dbae3e97dca71c8341df 100644 (file)
@@ -314,7 +314,7 @@ IA64FAULT vmx_vcpu_itr_d(VCPU *vcpu, u64 slot, u64 pte, u64 itir, u64 ifa)
         thash_purge_entries(vcpu, va, ps);
     gpfn = (pte & _PAGE_PPN_MASK)>> PAGE_SHIFT;
     gpte = lookup_domain_mpa(vcpu->domain, gpfn, NULL);
-    if (gpte & GPFN_IO_MASK)
+    if (gpte & _PAGE_IO)
         pte |= VTLB_PTE_IO;
     vcpu_get_rr(vcpu, va, &rid);
     rid &= RR_RID_MASK;
index cbfea2a614028bad133f700fd2719beba30e2533..5a6ed0a163685a72a2a57cb1912ec329f42f39a0 100644 (file)
@@ -372,8 +372,9 @@ vmx_hpw_miss(u64 vadr, u64 vec, REGS* regs)
                     return IA64_FAULT;
                 }
                 pte = lookup_domain_mpa(v->domain, pa_clear_uc(vadr), NULL);
-                if (v->domain != dom0 && (pte & GPFN_IO_MASK)) {
-                    emulate_io_inst(v, pa_clear_uc(vadr), 4, pte);
+                if (v->domain != dom0 && (pte & _PAGE_IO)) {
+                    emulate_io_inst(v, pa_clear_uc(vadr), 4,
+                                    (pte & _PFN_MASK) >> PAGE_SHIFT);
                     return IA64_FAULT;
                 }
                 physical_tlb_miss(v, vadr, type);
@@ -404,12 +405,13 @@ try_again:
             }
             gppa = thash_translate(data, vadr);
             pte = lookup_domain_mpa(v->domain, gppa, NULL);
-            if (pte & GPFN_IO_MASK) {
+            if (pte & _PAGE_IO) {
                 if (misr.sp)
                     panic_domain(NULL, "ld.s on I/O page not with UC attr."
                                  " pte=0x%lx\n", data->page_flags);
                 if (data->pl >= ((regs->cr_ipsr >> IA64_PSR_CPL0_BIT) & 3))
-                    emulate_io_inst(v, gppa, data->ma, pte);
+                    emulate_io_inst(v, gppa, data->ma, 
+                                    (pte & _PFN_MASK) >> PAGE_SHIFT);
                 else {
                     vcpu_set_isr(v, misr.val);
                     data_access_rights(v, vadr);
index 6a1c014c436f3ab4bdf29627a901492b0808e9f5..5f24e08e8744fee2213433e36e26bbed088e7159 100644 (file)
@@ -44,6 +44,7 @@
 #include <public/xen.h>
 #include <public/hvm/ioreq.h>
 #include <public/event_channel.h>
+#include <public/arch-ia64/hvm/memmap.h>
 #include <asm/vmx_phy_mode.h>
 #include <asm/processor.h>
 #include <asm/vmx.h>
@@ -553,11 +554,11 @@ typedef struct io_range {
 } io_range_t;
 
 static const io_range_t io_ranges[] = {
-       {VGA_IO_START, VGA_IO_SIZE, GPFN_FRAME_BUFFER},
-       {MMIO_START, MMIO_SIZE, GPFN_LOW_MMIO},
-       {LEGACY_IO_START, LEGACY_IO_SIZE, GPFN_LEGACY_IO},
-       {IO_SAPIC_START, IO_SAPIC_SIZE, GPFN_IOSAPIC},
-       {PIB_START, PIB_SIZE, GPFN_PIB},
+       {VGA_IO_START, VGA_IO_SIZE, GPFN_FRAME_BUFFER << PAGE_SHIFT},
+       {MMIO_START, MMIO_SIZE, GPFN_LOW_MMIO << PAGE_SHIFT},
+       {LEGACY_IO_START, LEGACY_IO_SIZE, GPFN_LEGACY_IO << PAGE_SHIFT},
+       {IO_SAPIC_START, IO_SAPIC_SIZE, GPFN_IOSAPIC << PAGE_SHIFT},
+       {PIB_START, PIB_SIZE, GPFN_PIB << PAGE_SHIFT},
 };
 
 // The P2M table is built in libxc/ia64/xc_ia64_hvm_build.c @ setup_guest()
@@ -571,7 +572,7 @@ static void vmx_build_io_physmap_table(struct domain *d)
                for (j = io_ranges[i].start;
                     j < io_ranges[i].start + io_ranges[i].size; j += PAGE_SIZE)
                        (void)__assign_domain_page(d, j, io_ranges[i].type,
-                                                  ASSIGN_writable);
+                                                  ASSIGN_writable | ASSIGN_io);
        }
 
 }
index f956b6889888b8579596cc33f27e687830e792bb..b1d5e25f46f181faeb316d77167ddae69196dd5d 100644 (file)
@@ -515,7 +515,7 @@ static u64 translate_phy_pte(VCPU *v, u64 pte, u64 itir, u64 va)
     phy_pte.val = pte;
     paddr = ((pte & _PAGE_PPN_MASK) & ps_mask) | (va & ~ps_mask);
     maddr = lookup_domain_mpa(d, paddr, NULL);
-    if (maddr & GPFN_IO_MASK)
+    if (maddr & _PAGE_IO)
         return -1;
 
     /* Ensure WB attribute if pte is related to a normal mem page,
index 4f880a7ca1582b9c8179629de4e827dd0db9d137..d51912fc213bc0e7bcb079d53fca695e06de7394 100644 (file)
@@ -886,6 +886,7 @@ flags_to_prot (unsigned long flags)
     res |= flags & ASSIGN_tlb_track ? _PAGE_TLB_TRACKING: 0;
 #endif
     res |= flags & ASSIGN_pgc_allocated ? _PAGE_PGC_ALLOCATED: 0;
+    res |= flags & ASSIGN_io ? _PAGE_IO: 0;
     
     return res;
 }
@@ -966,7 +967,7 @@ assign_domain_page(struct domain *d,
 {
     struct page_info* page = mfn_to_page(physaddr >> PAGE_SHIFT);
 
-    BUG_ON((physaddr & GPFN_IO_MASK) != GPFN_MEM);
+    BUG_ON((physaddr & _PAGE_PPN_MASK) != physaddr);
     BUG_ON(page->count_info != (PGC_allocated | 1));
     set_gpfn_from_mfn(physaddr >> PAGE_SHIFT, mpaddr >> PAGE_SHIFT);
     // because __assign_domain_page() uses set_pte_rel() which has
index c8f2dbebf95b54b0720f8c9cc64376a743f04813..2bc246726ef13c97cfad244072132753f936b3e8 100644 (file)
 
 #define _PAGE_PGC_ALLOCATED_BIT        59      /* _PGC_allocated */
 #define _PAGE_PGC_ALLOCATED    (__IA64_UL(1) << _PAGE_PGC_ALLOCATED_BIT)
-/* domVTI */
-#define GPFN_MEM               (0UL << 60)     /* Guest pfn is normal mem */
-#define GPFN_FRAME_BUFFER      (1UL << 60)     /* VGA framebuffer */
-#define GPFN_LOW_MMIO          (2UL << 60)     /* Low MMIO range */
-#define GPFN_PIB               (3UL << 60)     /* PIB base */
-#define GPFN_IOSAPIC           (4UL << 60)     /* IOSAPIC base */
-#define GPFN_LEGACY_IO         (5UL << 60)     /* Legacy I/O base */
-#define GPFN_GFW               (6UL << 60)     /* Guest Firmware */
-#define GPFN_HIGH_MMIO         (7UL << 60)     /* High MMIO range */
-
-#define GPFN_IO_MASK           (7UL << 60)     /* Guest pfn is I/O type */
+
+#define _PAGE_IO_BIT           60
+#define _PAGE_IO               (__IA64_UL(1) << _PAGE_IO_BIT)
 
 #else
 #define _PAGE_PROTNONE         (__IA64_UL(1) << 63)
@@ -341,7 +333,7 @@ set_pte_rel(volatile pte_t* ptep, pte_t pteval)
 #define pte_file(pte)          ((pte_val(pte) & _PAGE_FILE) != 0)
 #ifdef XEN
 #define pte_pgc_allocated(pte) ((pte_val(pte) & _PAGE_PGC_ALLOCATED) != 0)
-#define pte_mem(pte)   (!(pte_val(pte) & GPFN_IO_MASK) && !pte_none(pte))
+#define pte_mem(pte)   (!(pte_val(pte) & _PAGE_IO) && !pte_none(pte))
 #endif
 /*
  * Note: we convert AR_RWX to AR_RX and AR_RW to AR_R by clearing the 2nd bit in the
index ff26ad4eb40726f23d56fd2c9da939663231665d..90d06c90b8f6e469067c767f66903c17e65cefa6 100644 (file)
@@ -190,7 +190,7 @@ extern int init_domain_tlb(struct vcpu *v);
 extern void free_domain_tlb(struct vcpu *v);
 extern thash_data_t * vhpt_lookup(u64 va);
 extern unsigned long fetch_code(struct vcpu *vcpu, u64 gip, IA64_BUNDLE *pbundle);
-extern void emulate_io_inst(struct vcpu *vcpu, u64 padr, u64 ma, u64 pte);
+extern void emulate_io_inst(struct vcpu *vcpu, u64 padr, u64 ma, u64 iot);
 extern void emulate_io_update(struct vcpu *vcpu, u64 word, u64 d, u64 d1);
 extern int vhpt_enabled(struct vcpu *vcpu, uint64_t vadr, vhpt_ref_t ref);
 extern void thash_vhpt_insert(struct vcpu *v, u64 pte, u64 itir, u64 ifa,
index afb2a52164ee901b7ec2db0c392c09b6390ba302..76cb70fb1a1273898c4f87087cc16641aec931b6 100644 (file)
@@ -62,6 +62,10 @@ typedef unsigned long xen_pfn_t;
 /* WARNING: before changing this, check that shared_info fits on a page */
 #define MAX_VIRT_CPUS 64
 
+/* IO ports location for PV.  */
+#define IO_PORTS_PADDR          0x00000ffffc000000UL
+#define IO_PORTS_SIZE           0x0000000004000000UL
+
 #ifndef __ASSEMBLY__
 
 #define __anonymous_union __extension__ union
@@ -76,54 +80,6 @@ typedef unsigned long xen_ulong_t;
 
 #define INVALID_MFN       (~0UL)
 
-#define MEM_G   (1UL << 30)
-#define MEM_M   (1UL << 20)
-#define MEM_K   (1UL << 10)
-
-/* Guest physical address of IO ports space.  */
-#define IO_PORTS_PADDR          0x00000ffffc000000UL
-#define IO_PORTS_SIZE           0x0000000004000000UL
-
-#define MMIO_START       (3 * MEM_G)
-#define MMIO_SIZE        (512 * MEM_M)
-
-#define VGA_IO_START     0xA0000UL
-#define VGA_IO_SIZE      0x20000
-
-#define LEGACY_IO_START  (MMIO_START + MMIO_SIZE)
-#define LEGACY_IO_SIZE   (64*MEM_M)
-
-#define IO_PAGE_START (LEGACY_IO_START + LEGACY_IO_SIZE)
-#define IO_PAGE_SIZE  XEN_PAGE_SIZE
-
-#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE)
-#define STORE_PAGE_SIZE  XEN_PAGE_SIZE
-
-#define BUFFER_IO_PAGE_START (STORE_PAGE_START + STORE_PAGE_SIZE)
-#define BUFFER_IO_PAGE_SIZE  XEN_PAGE_SIZE
-
-#define BUFFER_PIO_PAGE_START (BUFFER_IO_PAGE_START + BUFFER_IO_PAGE_SIZE)
-#define BUFFER_PIO_PAGE_SIZE  XEN_PAGE_SIZE
-
-#define IO_SAPIC_START   0xfec00000UL
-#define IO_SAPIC_SIZE    0x100000
-
-#define PIB_START 0xfee00000UL
-#define PIB_SIZE 0x200000
-
-#define GFW_START        (4*MEM_G -16*MEM_M)
-#define GFW_SIZE         (16*MEM_M)
-
-/* Nvram belongs to GFW memory space  */
-#define NVRAM_SIZE       (MEM_K * 64)
-#define NVRAM_START      (GFW_START + 10 * MEM_M)
-
-#define NVRAM_VALID_SIG 0x4650494e45584948             // "HIXENIPF"
-struct nvram_save_addr {
-    unsigned long addr;
-    unsigned long signature;
-};
-
 struct pt_fpreg {
     union {
         unsigned long bits[2];
@@ -505,6 +461,9 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
 /* Internal only: associated with PGC_allocated bit */
 #define _ASSIGN_pgc_allocated           3
 #define ASSIGN_pgc_allocated            (1UL << _ASSIGN_pgc_allocated)
+/* Page is an IO page.  */
+#define _ASSIGN_io                      4
+#define ASSIGN_io                       (1UL << _ASSIGN_io)
 
 /* This structure has the same layout of struct ia64_boot_param, defined in
    <asm/system.h>.  It is redefined here to ease use.  */
@@ -640,6 +599,10 @@ DEFINE_XEN_GUEST_HANDLE(pfarg_load_t);
 #endif /* __ASSEMBLY__ */
 #endif /* XEN */
 
+#ifndef __ASSEMBLY__
+#include "arch-ia64/hvm/memmap.h"
+#endif
+
 #endif /* __HYPERVISOR_IF_IA64_H__ */
 
 /*
diff --git a/xen/include/public/arch-ia64/hvm/memmap.h b/xen/include/public/arch-ia64/hvm/memmap.h
new file mode 100644 (file)
index 0000000..10054b2
--- /dev/null
@@ -0,0 +1,88 @@
+/******************************************************************************
+ * memmap.h
+ *
+ * Copyright (c) 2008 Tristan Gingold <tgingold AT free fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __XEN_PUBLIC_HVM_MEMMAP_IA64_H__
+#define __XEN_PUBLIC_HVM_MEMMAP_IA64_H__
+
+#define MEM_G  (1UL << 30)
+#define MEM_M  (1UL << 20)
+#define MEM_K  (1UL << 10)
+
+/* Guest physical address of IO ports space.  */
+#define MMIO_START  (3 * MEM_G)
+#define MMIO_SIZE   (512 * MEM_M)
+
+#define VGA_IO_START  0xA0000UL
+#define VGA_IO_SIZE   0x20000
+
+#define LEGACY_IO_START  (MMIO_START + MMIO_SIZE)
+#define LEGACY_IO_SIZE   (64 * MEM_M)
+
+#define IO_PAGE_START  (LEGACY_IO_START + LEGACY_IO_SIZE)
+#define IO_PAGE_SIZE   XEN_PAGE_SIZE
+
+#define STORE_PAGE_START  (IO_PAGE_START + IO_PAGE_SIZE)
+#define STORE_PAGE_SIZE   XEN_PAGE_SIZE
+
+#define BUFFER_IO_PAGE_START  (STORE_PAGE_START + STORE_PAGE_SIZE)
+#define BUFFER_IO_PAGE_SIZE   XEN_PAGE_SIZE
+
+#define BUFFER_PIO_PAGE_START  (BUFFER_IO_PAGE_START + BUFFER_IO_PAGE_SIZE)
+#define BUFFER_PIO_PAGE_SIZE   XEN_PAGE_SIZE
+
+#define IO_SAPIC_START  0xfec00000UL
+#define IO_SAPIC_SIZE   0x100000
+
+#define PIB_START  0xfee00000UL
+#define PIB_SIZE   0x200000
+
+#define GFW_START  (4 * MEM_G - 16 * MEM_M)
+#define GFW_SIZE   (16 * MEM_M)
+
+/* domVTI */
+#define GPFN_FRAME_BUFFER  0x1 /* VGA framebuffer */
+#define GPFN_LOW_MMIO      0x2 /* Low MMIO range */
+#define GPFN_PIB           0x3 /* PIB base */
+#define GPFN_IOSAPIC       0x4 /* IOSAPIC base */
+#define GPFN_LEGACY_IO     0x5 /* Legacy I/O base */
+#define GPFN_HIGH_MMIO     0x6 /* High MMIO range */
+
+/* Nvram belongs to GFW memory space  */
+#define NVRAM_SIZE   (MEM_K * 64)
+#define NVRAM_START  (GFW_START + 10 * MEM_M)
+
+#define NVRAM_VALID_SIG  0x4650494e45584948 /* "HIXENIPF" */
+struct nvram_save_addr {
+    unsigned long addr;
+    unsigned long signature;
+};
+
+#endif /* __XEN_PUBLIC_HVM_MEMMAP_IA64_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */